package com.example.authsystem.entity;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import jakarta.persistence.*;
import java.time.LocalDateTime;

@Entity
@Table(name = "audit_logs", indexes = {
        @Index(name = "idx_username", columnList = "username"),
        @Index(name = "idx_action", columnList = "action"),
        @Index(name = "idx_timestamp", columnList = "timestamp"),
        @Index(name = "idx_ip_address", columnList = "ip_address"),
        @Index(name = "idx_target_user_id", columnList = "target_user_id")
})
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "审计日志实体")
public class AuditLog {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Schema(description = "日志ID", example = "1")
    private Long id;

    @Column(name = "username", length = 100)
    @Schema(description = "操作用户名", example = "admin")
    private String username;

    @Column(name = "action", length = 100, nullable = false)
    @Schema(description = "操作类型", example = "USER_LOGIN")
    private String action;

    @Column(name = "details", columnDefinition = "TEXT")
    @Schema(description = "操作详情", example = "用户登录成功")
    private String details;

    @Column(name = "ip_address", length = 45)
    @Schema(description = "操作IP地址", example = "192.168.1.100")
    private String ipAddress;

    @Column(name = "device_id", length = 100)
    @Schema(description = "设备标识", example = "device_123456")
    private String deviceId;

    @Column(name = "location", length = 200)
    @Schema(description = "操作位置", example = "北京市朝阳区")
    private String location;

    @Column(name = "target_user_id")
    @Schema(description = "目标用户ID（如果操作涉及其他用户）", example = "123")
    private Long targetUserId;

    @Column(name = "success", nullable = false)
    @Schema(description = "操作是否成功", example = "true")
    @Builder.Default
    private Boolean success = true;

    @Column(name = "error_message", columnDefinition = "TEXT")
    @Schema(description = "错误信息（如果操作失败）")
    private String errorMessage;

    @Column(name = "session_id", length = 100)
    @Schema(description = "会话ID", example = "session_789")
    private String sessionId;

    @Column(name = "user_agent", length = 500)
    @Schema(description = "用户代理信息")
    private String userAgent;

    @Column(name = "request_url", length = 500)
    @Schema(description = "请求URL", example = "/api/users/login")
    private String requestUrl;

    @Column(name = "request_method", length = 10)
    @Schema(description = "请求方法", example = "POST")
    private String requestMethod;

    @Column(name = "response_status")
    @Schema(description = "响应状态码", example = "200")
    private Integer responseStatus;

    @Column(name = "execution_time")
    @Schema(description = "执行时间（毫秒）", example = "156")
    private Long executionTime;

    @Column(name = "timestamp", nullable = false)
    @Schema(description = "操作时间")
    private LocalDateTime timestamp;

    @Column(name = "created_at", nullable = false, updatable = false)
    @Schema(description = "记录创建时间")
    private LocalDateTime createdAt;

    @PrePersist
    protected void onCreate() {
        if (createdAt == null) {
            createdAt = LocalDateTime.now();
        }
        if (timestamp == null) {
            timestamp = LocalDateTime.now();
        }
    }

    // 便捷的静态方法用于创建不同类型的审计日志
    public static AuditLog createLoginLog(String username, String ipAddress, String deviceId, String location) {
        return AuditLog.builder()
                .username(username)
                .action("USER_LOGIN")
                .details("用户登录成功")
                .ipAddress(ipAddress)
                .deviceId(deviceId)
                .location(location)
                .success(true)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static AuditLog createLogoutLog(String username, String ipAddress, Long sessionDuration) {
        return AuditLog.builder()
                .username(username)
                .action("USER_LOGOUT")
                .details("用户登出，会话时长: " + sessionDuration + " 分钟")
                .ipAddress(ipAddress)
                .success(true)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static AuditLog createRegistrationLog(String username, String email, String ipAddress) {
        return AuditLog.builder()
                .username(username)
                .action("USER_REGISTRATION")
                .details("新用户注册，邮箱: " + email)
                .ipAddress(ipAddress)
                .success(true)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static AuditLog createErrorLog(String username, String action, String errorMessage, String ipAddress) {
        return AuditLog.builder()
                .username(username)
                .action(action)
                .details("操作失败")
                .errorMessage(errorMessage)
                .ipAddress(ipAddress)
                .success(false)
                .timestamp(LocalDateTime.now())
                .build();
    }

    public static AuditLog createApiAccessLog(String username, String requestUrl, String method,
                                              Integer status, Long executionTime, String ipAddress) {
        return AuditLog.builder()
                .username(username)
                .action("API_ACCESS")
                .details("API访问: " + method + " " + requestUrl)
                .requestUrl(requestUrl)
                .requestMethod(method)
                .responseStatus(status)
                .executionTime(executionTime)
                .ipAddress(ipAddress)
                .success(status < 400)
                .timestamp(LocalDateTime.now())
                .build();
    }
}
